/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.brain.fina.mbean;

import com.brain.come.dto.DocumentoVentaDto;
import com.brain.conf.dto.TerceroDto;
import com.brain.core.common.ExportarExcelFinanzas;
import com.brain.core.common.ExportarExcelFinanzas.NotaCredito;
import com.brain.core.common.UtilCore;
import com.brain.core.dto.ParametroDto;
import com.brain.core.exception.DAOException;
import com.brain.core.manager.RecursosManager;
import com.brain.core.view.mbean.*;
import com.brain.core.view.util.ConstantesCore;
import com.brain.fina.dto.NotaCreditoDto;
import com.brain.fina.manager.NotaCreditoManager;
import com.brain.fina.view.util.ConstantesFina;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import javax.annotation.Resource;
import javax.faces.model.SelectItem;
import net.sf.jasperreports.engine.JRException;
import org.apache.log4j.Logger;
import org.primefaces.context.RequestContext;
import org.primefaces.event.SelectEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

/**
 * @author Greip Company
 * @since 09/01/2014
 * @version 1.0
 */
@Controller("notaCreditoMBean")
@Scope("session")
public class NotaCreditoMBean extends GenericMBean implements Serializable {

    /**
     * Guarda las acciones del sistema en un archivo de texto plano
     *
     * @since 09/01/2014
     */
    private static Logger logger = Logger.getLogger(NotaCreditoMBean.class);
    /**
     * objeto de la clase ApplicationMBean , acceso a la clase utilitaria de
     * configuración
     *
     * @since 09/01/2014
     */
    @Autowired
    private ApplicationMBean applicationMBean;
    /**
     * objeto de la clase SessionMBean
     *
     * @since 09/01/2014
     */
    @Autowired
    private SessionMBean sessionMBean;
    /**
     * Objeto que permite el acceso a la capa de datos de la clase
     * NotaCreditoManager
     *
     * @since 09/01/2014
     */
    @Autowired
    private NotaCreditoManager notaCreditoManager;
    /**
     * Objeto que permite acceder a la clase utilitaria de datos
     *
     * @since 09/01/2014
     */
    @Resource
    private RecursosManager recursosManager;
    /**
     * Objeto tipo lista de la clase NotaCreditoDto
     *
     * @since 09/01/2014
     */
    private List<NotaCreditoDto> lista;
    /**
     * objeto de la clase NotaCreditoDto
     *
     * @since 09/01/2014
     */
    private NotaCreditoDto dto;
    /**
     * objeto de la clase NotaCreditoDto
     *
     * @since 09/01/2014
     */
    private NotaCreditoDto filtroDto;
    /**
     * titulo del formulario
     *
     * @since 09/01/2014
     */
    private String keyTitulo = "nota.credito.panel";
    /**
     * arreglo de items de la clase SelectItem
     *
     * @since 09/01/2014
     */
    private SelectItem[] siEstadosBusqueda;
    /**
     * objeto tipo lista de la clase ParametroDto
     *
     * @since 09/01/2014
     */
    private List<ParametroDto> siMotivos;
    /**
     * objeto de la clase DocumentoVentaDto
     *
     * @since 09/01/2014
     */
    private DocumentoVentaDto documentoVentaDto;
    /**
     * objeto tipo Array de la clase NotaCreditoDto
     *
     * @since 09/01/2014
     */
    private NotaCreditoDto[] selectedNCs;
    /**
     * objeto tipo de la clase ExportarExcelFinanzas.NotaCredito
     *
     * @since 09/01/2014
     */
    private ExportarExcelFinanzas.NotaCredito ncExcel;
    private String tipoXls;
    private Boolean checkExcel;

    /**
     * Metodo constructor de la clase
     *
     * @since 09/01/2014
     */
    public NotaCreditoMBean() {
        filtroDto = new NotaCreditoDto();
        lista = null;
    }

    /**
     * Metodo que permite instanciar todos los objetos al iniciar el formulario
     *
     * @since 09/01/2014
     */
    public String iniciar() {
        this.lista = null;
        this.filtroDto = new NotaCreditoDto();
        this.filtroDto.setClienteDto(new TerceroDto());
        this.filtroDto.setDocumentoVentaDto(new DocumentoVentaDto());
        this.filtroDto.setEstado(ConstantesFina.ValoresConstantes.NOTA_CREDITO_COD_ESTADO_TODOS);
        this.filtroDto.setFechaInicio(UtilCore.Fecha.agregarDiasFechaDate(UtilCore.Fecha.obtenerFechaActualDate(), applicationMBean.getRangoFechasBusqueda() * -1));
        this.filtroDto.setFechaFin(UtilCore.Fecha.obtenerFechaActualDate());
        this.ncExcel = new ExportarExcelFinanzas.NotaCredito(true);
        this.selectedNCs = null;
        return notaCreditoManager.getUrlLista();
    }

    /**
     * Metodo que setea los valores del dto y construye el formulario para crear
     * un nuevo registro
     *
     * @since 09/01/2014
     * @return retorna la url de la nueva pagina
     */
    public String nuevo() {
        sessionMBean.setAccion(applicationMBean.getNuevo());
        sessionMBean.setTitulo(recursosManager.construirTitulo(keyTitulo, sessionMBean.getAccion()));
        this.dto = new NotaCreditoDto();
        this.dto.setMotivoDto(notaCreditoManager.obtenerParametroPorId(ConstantesCore.Parametro.PARAMETRO_NOTA_CREDITO_MOTIVO_DEVOLUCION));
        this.dto.setEstado(ConstantesFina.ValoresConstantes.NOTA_CREDITO_COD_ESTADO_ELABORACION);
        return notaCreditoManager.getUrl();
    }

    /**
     * Metodo que permite cargar los valores de un dto existente y construye el
     * formulario para editar un registro
     *
     * @since 09/01/2014
     * @return retorna la url de la pagina de editado
     */
    public String editar() {
        sessionMBean.setAccion(applicationMBean.getEditar());
        sessionMBean.setTitulo(recursosManager.construirTitulo(keyTitulo, sessionMBean.getAccion()));
        return notaCreditoManager.getUrl();
    }

    /**
     * Metodo que permite ver los datos existentes de un dto , sin opción a
     * editar o modificar algún valor
     *
     * @since 09/01/2014
     * @return retorna la url de la pagina de financiamientoLetra
     */
    public String ver() {
        sessionMBean.setAccion(applicationMBean.getVer());
        sessionMBean.setTitulo(recursosManager.construirTitulo(keyTitulo, sessionMBean.getAccion()));
        return notaCreditoManager.getUrl();
    }

    /**
     * Metodo que permite buscar todos los registros de la clase NotaCreditoDto
     *
     * @since 09/01/2014
     */
    public void buscar() {
        try {
            this.setLista(this.notaCreditoManager.obtenerNotasCredito(filtroDto));
        } catch (DAOException ex) {
            logger.error(ex);
            showError(UtilCore.Internacionalizacion.getMensajeInternacional("form.general.mensaje.transaccion.error"));
        }
    }

    public void documentoVentaSelect(SelectEvent event) {
        try {
            this.documentoVentaDto = (DocumentoVentaDto) event.getObject();
            this.dto.setDocumentoVentaDto(this.documentoVentaDto);
            this.dto.setMonedaDto(this.documentoVentaDto.getMonedaDto());
            this.dto.setMonto(this.documentoVentaDto.getTotal());
            calValores();
            this.dto.setClienteDto(this.documentoVentaDto.getClienteDto());
        } catch (Exception ex) {
            logger.error(ex);
            showError(UtilCore.Internacionalizacion.getMensajeInternacional("form.general.mensaje.transaccion.error"));
        }
    }

    /**
     * Metodo que permite imprimir los valores existentes de un dto seleccionado
     * Se exportan todos los detalles asociados al dto seleccionado (Letras)
     *
     * @since 09/01/2014
     * @return retorna un valor vacio
     */
    public String imprimirDto() {
        try {
            String nombreArchivoReporte = "NOTA_CREDITO_NRO_" + this.dto.getId();
            HashMap parametros = new HashMap();
            parametros.put("P_NOTA_CREDITO", BigDecimal.valueOf(this.dto.getId()));
            recursosManager.viewReportePdf(parametros, "NotaCredito", nombreArchivoReporte);
            return null;
        } catch (FileNotFoundException ex) {
            showError("EL ARCHIVO NO SE ENCUENTRA");
            logger.error(ex);
        } catch (JRException ex) {
            logger.error(ex);
            showError("ERROR EN LA COMPILACIÓN DEL REPORTE");
        } catch (IOException ex) {
            showError("EL ARCHIVO ESTÁ DAÑADO");
            logger.error(ex);
        } catch (SQLException ex) {
            logger.error(ex);
            showError("ERROR EN LA CONSULTA DEL REPORTE");
        } finally {
            return null;
        }
    }

    /**
     * Metodo que permite calcular el Impuesto de venta , el Montode Impuesto y
     * el total
     *
     * @since 09/01/2014
     *
     */
    public void calValores() {
        this.dto.setImpuestoVenta(this.documentoVentaDto.getImpuesto());
        this.dto.setMontoImpuestoVenta(this.dto.getMonto().multiply(UtilCore.Numero.valorEnPorcentaje(this.dto.getImpuestoVenta(), applicationMBean.getPrecisionDecimales())));
        this.dto.setTotal(this.dto.getMonto().add(this.dto.getMontoImpuestoVenta()));
    }

    /**
     * Metodo que permite gestionar las acciones DML del objeto dto de la clase
     * FinanciamientoLetraDto
     *
     * @since 09/01/2014
     * @return retorna la url de la pagina de financiamientoLetra o ún valor
     * nulo en caso pase un error
     */
    public String guardar() throws DAOException {
        String to = null;
        String mensajeTrx = "";
        this.dto.setUsuarioDto(sessionMBean.getSessionUsuarioDto());
        this.dto.setTerminal(sessionMBean.getSessionTerminal());
        this.dto.setFecha(UtilCore.Fecha.obtenerFechaActualDate());
        UtilCore.General.redondearNumerosDto(this.dto, applicationMBean.getPrecisionDecimales());
        if (this.dto.getNumero() != null | this.dto.getSerie() != null) {
            this.dto.setEstado(ConstantesFina.ValoresConstantes.NOTA_CREDITO_COD_ESTADO_CONFIRMADO);
        } else {
            this.dto.setEstado(ConstantesFina.ValoresConstantes.NOTA_CREDITO_COD_ESTADO_ELABORACION);
        }

        if (notaCreditoManager.validarSerieNumero(dto, sessionMBean.getAccion()) > 0) {
            showError(UtilCore.Internacionalizacion.getMensajeInternacional("nota.credito.mensaje.error.numero.documento.duplicado"));
            return to;
        } else if (excedeTotalNotasCreditos(this.dto.getDocumentoVentaDto().getId())) {
            showError(UtilCore.Internacionalizacion.getMensajeInternacional("nota.credito.mensaje.error.tota.credito.excedido"));
            return to;
        } else {
            if (sessionMBean.getAccion() == applicationMBean.getNuevo()) {
                try {
                    UtilCore.General.toUpperCaseDto(this.dto);
                    this.dto.setUsuarioCreacionDto(sessionMBean.getSessionUsuarioDto());
                    this.dto.setTerminalCreacion(sessionMBean.getSessionTerminal());
                    this.dto.setFechaCreacion(UtilCore.Fecha.obtenerFechaActualDate());
                    this.notaCreditoManager.nuevo(this.dto);
                    mensajeTrx = UtilCore.Internacionalizacion.getMensajeInternacional("form.general.mensaje.transaccion.ok");
                    showMessage(mensajeTrx);
                    to = retroceder();
                } catch (Exception ex) {
                    logger.error("ERROR DE SISTEMA - NOTA CREDITO : ", ex);
                    showError(UtilCore.Internacionalizacion.getMensajeInternacional("form.general.mensaje.transaccion.error"));
                    to = null;
                }
            }
            if (sessionMBean.getAccion() == applicationMBean.getEditar()) {
                try {
                    UtilCore.General.toUpperCaseDto(this.dto);
                    this.notaCreditoManager.editar(this.dto);
                    mensajeTrx = UtilCore.Internacionalizacion.getMensajeInternacional("form.general.mensaje.transaccion.ok");
                    showMessage(mensajeTrx);
                    to = retroceder();
                } catch (Exception ex) {
                    logger.error("ERROR DE SISTEMA - NOTA CREDITO ", ex);
                    showError(UtilCore.Internacionalizacion.getMensajeInternacional("form.general.mensaje.transaccion.error"));
                    to = null;
                }
            }
        }
        return to;
    }
     /**
     * Metodo que permite validar por el codigo , si el total de Notas de Credito excede al actual
     *
     * @since 09/01/2014
     * @param id es el id que se enviará para la validación
     * @return retorna un valor booleano 
     */

    public Boolean excedeTotalNotasCreditos(Long id) {

        Boolean excede = Boolean.FALSE;
        BigDecimal suma = BigDecimal.ZERO;
        try {
            suma = this.notaCreditoManager.obtenerSumaCreditos(id);
            System.out.println("SUMA: " + suma);
        } catch (Exception e) {
            logger.error(e);
        }
        System.out.println("MONTO: " + this.dto.getMonto());
        System.out.println("TOTAL DV: " + this.dto.getDocumentoVentaDto().getTotal());
        if ((suma.add(this.dto.getMonto())).compareTo(this.dto.getDocumentoVentaDto().getTotal()) > 0) {
            excede = Boolean.TRUE;
        }
        return excede;
    }

    /**
     * Metodo que permite retroceder , del formulario actual . A la lista de
     * búsqueda
     *
     * @since 09/01/2014
     * @return retorna la url de la pagina de busqueda de la clase
     * FinanciamientoLetraDto
     */
    public String retroceder() {
        sessionMBean().setAccion(applicationMBean.getLista());
        sessionMBean().setTitulo(recursosManager.construirTitulo(keyTitulo, sessionMBean().getAccion()));
        filtroDto = new NotaCreditoDto();
        filtroDto.setClienteDto(new TerceroDto());
        filtroDto.setDocumentoVentaDto(new DocumentoVentaDto());
        buscar();
        return notaCreditoManager.getUrlLista();
    }

    /**
     * Metodo que permite seleccionar los valores de la lista a exportar (Filas)
     *
     * @since 09/01/2014
     */
    private void generarExcelSeleccionadosNotaCredito() {
        this.notaCreditoManager.generarExcelSeleccionados(ncExcel, selectedNCs);
    }

    /**
     * Metodo que permite exportar los valores de toda la busqueda de la tabla
     *
     * @since 09/01/2014
     *
     */
    private void generarExcelPorTablaNotaCredito() {
        this.notaCreditoManager.generarExcelPorTabla(ncExcel, lista);
    }

    /**
     * Metodo que permite exportar los valores seleccionados a un documento de
     * excel
     *
     * @since 09/01/2014
     *
     */
    public void exportarExcel() {
        if (this.tipoXls.equals("T")) {
            generarExcelPorTablaNotaCredito();
        } else if (this.tipoXls.equals("S")) {
            generarExcelSeleccionadosNotaCredito();
        }
    }

    /**
     * Metodo que permite cargar valores a un nuevo pop-up donde , se
     * seleccionarán valores a exportar
     *
     * @since 09/01/2014
     */
    public void cargarPopupExportarExcel(String tipo) {
        RequestContext context = RequestContext.getCurrentInstance();
        boolean resultado = true;
        this.tipoXls = tipo;
        if (tipo.equals("T")) {
            if (lista.isEmpty()) {
                resultado = false;
                this.recursosManager.showWarning(UtilCore.Internacionalizacion.getMensajeInternacional("mensaje.selecc.nota.credito"));
            }
        } else if (tipo.equals("S")) {

            if (selectedNCs.length <= 0) {
                resultado = false;
                this.recursosManager.showWarning(UtilCore.Internacionalizacion.getMensajeInternacional("mensaje.selecc.nota.credito"));
            }

        }
        if (resultado) {
            this.ncExcel = new ExportarExcelFinanzas.NotaCredito(true);
            this.checkExcel = Boolean.TRUE;
        }
        context.addCallbackParam("CallbackParam", resultado);
    }

    /**
     * Metodo que permite seleccionar un valor de el pop-up , para después
     * exportarlo
     *
     * @since 09/01/2014
     *
     */
    public void onChangeChekExcel() {
        this.ncExcel = notaCreditoManager.onChangeChekExcel(checkExcel);
    }
 /**
     * Metodo que permite autocompletar una lista de documentos de venta
     *
     * @since 09/01/2014
     * @param query datos digitados por el usuario que facilitan la busqueda de
     * un registro
     * @return retorna una lista de documentos de venta
     */
    public List<DocumentoVentaDto> autoCompletarDocumentosVentas(String query) {
        return notaCreditoManager.listaDocumentosVentas(query);
    }

    public ApplicationMBean getApplicationMBean() {
        return applicationMBean;
    }

    public void setApplicationMBean(ApplicationMBean applicationMBean) {
        this.applicationMBean = applicationMBean;
    }

    public NotaCreditoDto getDto() {
        return dto;
    }

    public void setDto(NotaCreditoDto dto) {
        this.dto = dto;
    }

    public NotaCreditoDto getFiltroDto() {
        return filtroDto;
    }

    public void setFiltroDto(NotaCreditoDto filtroDto) {
        this.filtroDto = filtroDto;
    }

    public String getKeyTitulo() {
        return keyTitulo;
    }

    public void setKeyTitulo(String keyTitulo) {
        this.keyTitulo = keyTitulo;
    }

    public List<NotaCreditoDto> getLista() {
        return lista;
    }

    public void setLista(List<NotaCreditoDto> lista) {
        this.lista = lista;
    }

    public static Logger getLogger() {
        return logger;
    }

    public static void setLogger(Logger logger) {
        NotaCreditoMBean.logger = logger;
    }

    public NotaCreditoManager getNotaCreditoManager() {
        return notaCreditoManager;
    }

    public void setNotaCreditoManager(NotaCreditoManager notaCreditoManager) {
        this.notaCreditoManager = notaCreditoManager;
    }

    public RecursosManager getRecursosManager() {
        return recursosManager;
    }

    public void setRecursosManager(RecursosManager recursosManager) {
        this.recursosManager = recursosManager;
    }

    public SessionMBean getSessionMBean() {
        return sessionMBean;
    }

    public void setSessionMBean(SessionMBean sessionMBean) {
        this.sessionMBean = sessionMBean;
    }

    public SelectItem[] getSiEstadosBusqueda() {
        siEstadosBusqueda = notaCreditoManager.siTiposNotaCreditoTodos();
        return siEstadosBusqueda;
    }

    public void setSiEstadosBusqueda(SelectItem[] siEstadosBusqueda) {
        this.siEstadosBusqueda = siEstadosBusqueda;
    }

    public List<ParametroDto> getSiMotivos() {
        this.siMotivos = recursosManager.obtenerParametrosActivosPorCatalogoSistema(ConstantesFina.Catalogo.NOTA_CREDITO_MOTIVOS);
        return siMotivos;
    }

    public void setSiMotivos(List<ParametroDto> siMotivos) {
        this.siMotivos = siMotivos;
    }

    public DocumentoVentaDto getDocumentoVentaDto() {
        return documentoVentaDto;
    }

    public void setDocumentoVentaDto(DocumentoVentaDto documentoVentaDto) {
        this.documentoVentaDto = documentoVentaDto;
    }

    public NotaCreditoDto[] getSelectedNCs() {
        return selectedNCs;
    }

    public void setSelectedNCs(NotaCreditoDto[] selectedNCs) {
        this.selectedNCs = selectedNCs;
    }

    public NotaCredito getNcExcel() {
        return ncExcel;
    }

    public void setNcExcel(NotaCredito ncExcel) {
        this.ncExcel = ncExcel;
    }

    public String getTipoXls() {
        return tipoXls;
    }

    public void setTipoXls(String tipoXls) {
        this.tipoXls = tipoXls;
    }

    public Boolean getCheckExcel() {
        return checkExcel;
    }

    public void setCheckExcel(Boolean checkExcel) {
        this.checkExcel = checkExcel;
    }
}
